﻿using System.Reflection;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MugenInjection.Infrastructure;
using MugenInjection.Parameters;
using TestModels.Class;
using Should;

namespace MugenInjectionTest.Parameters
{
    [TestClass]
    public class ConstructorParameterTest
    {
        [TestMethod]
        public void CanResolveNamedTest()
        {
            ConstructorInfo falseConstructor = typeof(ParameterTestModel).GetConstructor(InjectorUtils.EmptyTypes);
            ConstructorInfo trueConstructor = typeof(ParameterTestModel).GetConstructor(new[] { typeof(string) });

            var parameter = new ConstructorParameter("param1", string.Empty);
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeTrue();

            parameter = new ConstructorParameter("param1", context => string.Empty);
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeTrue();

            parameter = new ConstructorParameter("param1", typeof(string), string.Empty);
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeTrue();

            parameter = new ConstructorParameter("param1", context => string.Empty, typeof(string));
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeTrue();


            parameter = new ConstructorParameter("param4", typeof(string), string.Empty);
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeFalse();

            parameter = new ConstructorParameter("param4", context => string.Empty, typeof(string));
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeFalse();
        }

        [TestMethod]
        public void CanResolveIndexTest()
        {
            ConstructorInfo falseConstructor = typeof(ParameterTestModel).GetConstructor(InjectorUtils.EmptyTypes);
            ConstructorInfo trueConstructor = typeof(ParameterTestModel).GetConstructor(new[] { typeof(string) });

            var parameter = new ConstructorParameter(0, string.Empty);
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeTrue();

            parameter = new ConstructorParameter(0, context => string.Empty);
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeTrue();

            parameter = new ConstructorParameter(0, typeof(string), string.Empty);
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeTrue();

            parameter = new ConstructorParameter(0, context => string.Empty, typeof(string));
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeTrue();

            parameter = new ConstructorParameter(1, typeof(string), string.Empty);
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeFalse();

            parameter = new ConstructorParameter(1, context => string.Empty, typeof(string));
            parameter.CanResolve(falseConstructor, null).ShouldBeFalse();
            parameter.CanResolve(trueConstructor, trueConstructor.GetParameters()[0]).ShouldBeFalse();
        }

         [TestMethod]
         public void GetValueTest()
         {
             var value = new object();
             var value1 = new object();

             var parameter = new ConstructorParameter("param1", value);
             parameter.GetValue(new ParameterContext(null, null)).ShouldEqual(value);

             parameter = new ConstructorParameter("param1", context => value1);
             parameter.GetValue(new ParameterContext(null, null)).ShouldEqual(value1);
         }
    }
}